"use strict"

const multiparty = require('multiparty');
const fs = require('fs');
const constants = require('../util/constants');
const mysqlUtil = require('../util/mysqlUtil');
const dbUtil = require('../util/dbUtil');
const Q = require('q');
const rd = require('rd');
const path = require('path');
const decompress = require('decompress');
const decompressUnzip = require('decompress-unzip');


/**
 * 上传升级包
 * @param  {[type]} req [description]
 * @param  {[type]} res [description]
 * @return {[type]}     [description]
 */
let doUpload = (req, res) => {
    // 1. 获取上传文件路径
    let _getFilePath = () => {
        let deferred = Q.defer();

        let params = [constants.UPGRADE_PACKAGE_FILE_PATH];
        mysqlUtil.exec("select * from t_config where name in (?)", [params], (err, result) => {
            var obj = {};
            for (let r of result) {
                if (r.name === constants.UPGRADE_PACKAGE_FILE_PATH) {
                    obj.uploadPath = r.value;
                }
            }
            deferred.resolve(obj);
        });
        return deferred.promise;
    };

    // 2. 上传文件
    let _uploadFile = data => {
        let deferred = Q.defer();
        let form = new multiparty.Form(); // 解析一个文件上传
        form.encoding = 'utf-8'; //设置编码
        form.uploadDir = data.uploadPath; //设置文件存储路径
        form.maxFilesSize = 200 * 1024 * 1024; //设置单文件大小限制，form.maxFields = 1000;  设置所以文件的大小总和
        form.parse(req, (err, fields, files) => {
            let file = files.file1[0];
            let obj = {
                uploadPath: data.uploadPath,
                originalFilename: file.originalFilename,
                filePath: file.path,
                fileName: file.path.substring(file.path.lastIndexOf(constants.PATH_SEPARATOR) + 1, file.path.length)
            };
            deferred.resolve(obj);
        });
        return deferred.promise;
    };

    // 3. 解压缩上传的zip文件
    let _unZipFile = data => {
        let deferred = Q.defer();
        data.unzipPath = data.filePath.replace(".zip", "");

        decompress(data.filePath, data.unzipPath, {
            plugins: [
                decompressUnzip()
            ]
        }).then(() => {
            console.log('Files decompressed');
            deferred.resolve(data);
        });

        return deferred.promise;
    };

    // 4. 读取上传的文件
    let _readFiles = data => {
        console.log('--------------------------');
        let deferred = Q.defer();

        rd.readFile(data.unzipPath, (err, files) => {
            if (err) throw err;

            let appInfos = getAppsInfo(files); // 根据上传的文件获取包含了哪些APP

            // 插入升级包记录
            let sqlObjs = [];
            let sql1Objs = [];
            let ids = [];
            for (let appInfo of appInfos) {
                let id = dbUtil.getUuid();
                let sql = "insert into t_ug_package(id, name, appname_cn, appname_en, description, create_userid, create_username, create_time, is_publish, file_path) values(?,?,?,?,?,?,?,now(),0,?)";
                sqlObjs.push({ sql: sql, values: [id, '', '', appInfo.appname, '', req.session.user.code, req.session.user.name, appInfo.filepath] });
                ids.push(id);

                for (let file of appInfo.files) {
                    var filename = file.substring(file.lastIndexOf('/') + 1, file.length);
                    let sql1 = "insert into t_ug_package_file(id, file_path, file_name, package_id) values(uuid(), ?, ?, ?)";
                    sql1Objs.push({ sql: sql1, values: [file, filename, id] });
                }
            }
            mysqlUtil.exec_batch(sqlObjs, null, function() {
                // 更新升级包的中文名
                let sql1 = "update t_ug_package p set p.appname_cn = (select a.cnname from t_ug_appname a where a.enname=p.appname_en) where p.id in (?)";
                mysqlUtil.exec(sql1, ids);

                mysqlUtil.exec_batch(sql1Objs);
            });

            data.appCount = sqlObjs.length;
            deferred.resolve(data);
        });

        return deferred.promise;
    };

    // 开始处理
    _getFilePath().then(_uploadFile).then(_unZipFile).then(_readFiles).done(data => {
        data.success = true;

        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(data));
    }, () => {
        data.success = false;

        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(data));
    });
};

/**
 * 删除升级包信息及文件
 */
let remove = (req, res) => {
    let id = req.body.id || '';

    // 1. 获取升级包信息
    let _getPackage = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_ug_package where id=?", [id], (err, result) => {
            deferred.resolve(result[0]);
        });
        return deferred.promise;
    };

    // 2. 删除数据库表t_ug_package_file相关内容
    let _removePackageFileData = (data) => {
        let deferred = Q.defer();
        mysqlUtil.exec("delete from t_ug_package_file where package_id=?", [id], (err, result) => {
            deferred.resolve(data);
        });
        return deferred.promise;
    };

    // 3. 删除数据库表t_ug_package_file相关内容
    let _removePackageProjectData = (data) => {
        let deferred = Q.defer();
        mysqlUtil.exec("delete from t_ug_package_project where package_id=?", [id], (err, result) => {
            deferred.resolve(data);
        });
        return deferred.promise;
    };

    // 4. 删除数据库表t_ug_package的内容
    let _removePackageData = (data) => {
        let deferred = Q.defer();
        mysqlUtil.exec("delete from t_ug_package where id=?", [id], (err, result) => {
            deferred.resolve(data);
        });
        return deferred.promise;
    };

    // 5. 删除物理文件(解压缩的文件)
    let _removePackageFile1 = (data) => {
        let deferred = Q.defer();

        var folder_exists = fs.existsSync(data.file_path);
        if (folder_exists == true) {
            deleteFolder(data.file_path);
        }
        deferred.resolve(data);
        return deferred.promise;
    };

    // 开始处理
    _getPackage().then(_removePackageFileData).then(_removePackageProjectData).then(_removePackageData).then(_removePackageFile1).done(data => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    }, (data) => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: false }));
    });
};

/**
 * 删除包文件
 * @param  {[type]} req [description]
 * @param  {[type]} res [description]
 * @return {[type]}     [description]
 */
let removePackageFile = (req, res) => {
    let id = req.body.id || '';

    // 1. 获取升级包信息
    let _getPackage = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_upgrade_package where id=?", [id], (err, result) => {
            deferred.resolve(result[0]);
        });
        return deferred.promise;
    };

    // 2. 删除数据库表t_upgrade_package_file相关内容
    let _removePackageFileData = (data) => {
        let deferred = Q.defer();
        mysqlUtil.exec("delete from t_upgrade_package_file where upgrade_package_id=?", [id], (err, result) => {
            deferred.resolve(data);
        });
        return deferred.promise;
    };

    // 3. 删除数据库表t_upgrade_package的内容
    let _updatePackageData = (data) => {
        let deferred = Q.defer();
        mysqlUtil.exec("update t_upgrade_package set original_file_name=null, original_file_path=null, original_file_view_name=null, file_count=0 where id=?", [id], (err, result) => {
            deferred.resolve(data);
        });
        return deferred.promise;
    };

    // 4. 删除物理文件(解压缩的文件)
    let _removePackageFile1 = (data) => {
        let deferred = Q.defer();

        var folder_exists = fs.existsSync(data.unzip_file_path);
        if (folder_exists == true) {
            deleteFolder(data.unzip_file_path);
        }
        deferred.resolve(data);
        return deferred.promise;
    };

    // 5. 删除物理文件(压缩的文件)
    let _removePackageFile2 = (data) => {
        let deferred = Q.defer();

        if (fs.existsSync(data.original_file_path)) {
            fs.unlink(data.original_file_path, function() {
                deferred.resolve(data);
            });
        } else {
            deferred.resolve(data);
        }
        return deferred.promise;
    };

    // 开始处理
    _getPackage().then(_removePackageFileData).then(_updatePackageData).then(_removePackageFile1).then(_removePackageFile2).done(data => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    }, (data) => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: false }));
    });
};

let doMergeUpgradePackage = (req, res, upgradeProjectObj, upgradePackages) => {

};

let deleteFolder = path => {
    var files = [];
    if (fs.existsSync(path)) {
        files = fs.readdirSync(path);
        files.forEach(function(file, index) {
            var curPath = path + "/" + file;
            if (fs.statSync(curPath).isDirectory()) {
                deleteFolder(curPath);
            } else {
                fs.unlinkSync(curPath);
            }
        });
        fs.rmdirSync(path);
    }
};

/**
 * 根据文件获取所有的app名字
 * 
 * @param  {[type]} files [description]
 * @return {[type]}       [description]
 */
let getAppsInfo = files => {
    let appInfos = [];
    let tag1 = constants.PATH_SEPARATOR + 'apps' + constants.PATH_SEPARATOR;
    let tag2 = constants.PATH_SEPARATOR + 'coms' + constants.PATH_SEPARATOR;

    for (let file of files) {
        if (file.indexOf(tag1) !== -1) {
            let str = file.substring(file.indexOf(tag1) + tag1.length, file.length);
            let appname = str.substring(0, str.indexOf(constants.PATH_SEPARATOR));
            appInfos.push({
                appname: appname,
                filepath: file.substring(0, file.indexOf(appname)) + appname + constants.PATH_SEPARATOR
            });
        } else if (file.indexOf(tag2) !== -1) {
            let str = file.substring(file.indexOf(tag2) + tag2.length, file.length);
            let appname = str.substring(0, str.indexOf(constants.PATH_SEPARATOR));
            appInfos.push({
                appname: appname,
                filepath: file.substring(0, file.indexOf(appname)) + appname + constants.PATH_SEPARATOR
            });
        }
    }

    appInfos = uniqueAppInfo(appInfos);

    for (var i = 0; i < appInfos.length; i++) {
        var appname = appInfos[i].appname;
        appInfos[i].files = [];

        for (var j = 0; j < files.length; j++) {
            if (files[j].indexOf(constants.PATH_SEPARATOR + appname + constants.PATH_SEPARATOR) !== -1) {
                appInfos[i].files.push(files[j]);
            }
        }
    }
    return appInfos;
}

// JS数组去除重复
let uniqueAppInfo = (appInfos) => {
    var tmp = [];
    for (var i = 0; i < appInfos.length; i++) {
        var exists = false;
        for (var j = 0; j < tmp.length; j++) {
            if (appInfos[i].appname === tmp[j].appname) {
                exists = true;
            }
        }
        if (!exists) {
            tmp.push(appInfos[i]);
        }
    }

    return tmp;
}

exports.doUpload = doUpload;
exports.remove = remove;
exports.removePackageFile = removePackageFile;